from django.core.files.storage import default_storage
from django.db import models

# Create your models here.
from django.db import models
from django.utils import timezone

from Customer.models import CustomUser, CustomOssStorage
from DjangoProject7 import settings


class EventCategory(models.Model):
    """活动分类"""
    name = models.CharField(max_length=50, unique=True, verbose_name='分类名称')
    description = models.TextField(blank=True, verbose_name='分类描述')
    icon = models.CharField(max_length=50, blank=True, verbose_name='图标')
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = '活动分类'
        verbose_name_plural = '活动分类'

    def __str__(self):
        return self.name


class Event(models.Model):
    """活动模型"""
    STATUS_CHOICES = (
        ('draft', '草稿'),
        ('pending', '待审核'),#新增
        ('published', '已发布'),
        ('cancelled', '已取消'),
        ('completed', '已完成'),
        ('rejected', '已拒绝'),#新增
    )

    title = models.CharField(max_length=200, verbose_name='活动标题')
    description = models.TextField(verbose_name='活动描述')
    organizer = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='organized_events')
    category = models.ForeignKey(EventCategory, on_delete=models.SET_NULL, null=True, verbose_name='活动分类')

    # 时间信息
    start_time = models.DateTimeField(verbose_name='开始时间')
    end_time = models.DateTimeField(verbose_name='结束时间')
    registration_deadline = models.DateTimeField(verbose_name='报名截止时间')

    # 地点信息
    location = models.CharField(max_length=200, verbose_name='活动地点')
    latitude = models.FloatField(verbose_name='纬度')
    longitude = models.FloatField(verbose_name='经度')
    location_details = models.TextField(blank=True, verbose_name='地点详情')

    # 人数限制
    max_participants = models.IntegerField(verbose_name='最大参与人数')
    current_participants = models.IntegerField(default=0, verbose_name='当前报名人数')

    # 活动状态
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft')

    # 费用信息
    is_free = models.BooleanField(default=True, verbose_name='是否免费')
    fee = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name='费用')

    # 统计信息
    views_count = models.IntegerField(default=0, verbose_name='浏览数')
    likes_count = models.IntegerField(default=0, verbose_name='点赞数')

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['status', 'start_time']),
            models.Index(fields=['latitude', 'longitude']),
        ]

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        """重写save方法，在状态变化时触发积分奖励 - 增强版"""
        import traceback

        # 获取调用堆栈信息，帮助诊断调用来源
        stack = traceback.extract_stack()
        caller_info = "Unknown"
        for frame in stack[-5:]:  # 查看最近5个调用帧
            if 'save' not in frame.name and 'event' in frame.filename.lower():
                caller_info = f"{frame.filename}:{frame.lineno} - {frame.name}"
                break

        print(f"🔍 [Event保存] 开始 - 调用者: {caller_info}")
        print(f"🔍 [Event保存] 活动: {self.title if hasattr(self, 'title') else 'No Title'}")
        print(f"🔍 [Event保存] 当前状态: {self.status}")

        # 记录旧状态（如果存在）
        old_status = None
        is_new_event = not self.pk  # 检查是否是新建的活动

        if self.pk:
            try:
                old_event = Event.objects.get(pk=self.pk)
                old_status = old_event.status
                print(f"🔍 [Event保存] 旧状态: {old_status}")
            except Event.DoesNotExist:
                print(f"🔍 [Event保存] 新活动创建")
                old_status = None
        else:
            print(f"🔍 [Event保存] 新活动创建")
            old_status = None

        # 调用父类保存方法
        super().save(*args, **kwargs)
        print(f"🔍 [Event保存] 保存完成，新状态: {self.status}")

        # === 新增：自动为活动创建者报名 ===
        if is_new_event and self.status in ['published', 'pending']:
            print(f"🎯 [Event保存] 新活动创建，自动为组织者 {self.organizer.username} 报名")
            try:
                # 检查是否已经报名
                existing_registration = EventRegistration.objects.filter(
                    event=self,
                    user=self.organizer
                ).first()

                if not existing_registration:
                    # 创建组织者报名记录
                    EventRegistration.objects.create(
                        event=self,
                        user=self.organizer,
                        status='registered'
                    )
                    print(f"✅ [Event保存] 组织者自动报名成功")

                    # 更新当前报名人数
                    self.current_participants = self.registrations.filter(status='registered').count()
                    # 使用update避免递归调用save
                    Event.objects.filter(pk=self.pk).update(current_participants=self.current_participants)
                    print(f"✅ [Event保存] 更新报名人数: {self.current_participants}")
                else:
                    print(f"🔍 [Event保存] 组织者已报名，跳过自动报名")

            except Exception as e:
                print(f"❌ [Event保存] 组织者自动报名失败: {str(e)}")
                traceback.print_exc()

        # 检查状态变化并处理积分
        if old_status is not None and old_status != self.status:
            print(f"✅ [Event保存] 检测到状态变化: {old_status} -> {self.status}")
            print(
                f"🔍 [Event保存] 检查是否触发积分: pending->published? {old_status == 'pending' and self.status == 'published'}")

            if old_status == 'pending' and self.status == 'published':
                print(f"🎯 [Event保存] 符合积分奖励条件!")
                try:
                    from .services import PointService
                    print(f"🔍 [Event保存] 调用 PointService.handle_event_status_change")
                    success, message = PointService.handle_event_status_change(self, old_status, self.status)
                    if success:
                        print(f"✅ [Event保存] 积分奖励成功: {message}")
                    else:
                        print(f"❌ [Event保存] 积分奖励失败: {message}")
                except Exception as e:
                    print(f"💥 [Event保存] 积分处理异常: {str(e)}")
                    traceback.print_exc()
            else:
                print(f"🔍 [Event保存] 状态变化不触发积分奖励")
        else:
            print(f"🔍 [Event保存] 状态未变化，跳过积分处理")

        print(f"🔍 [Event保存] 结束")
    @property
    def is_full(self):
        return self.current_participants >= self.max_participants

    @property
    def can_register(self):
        from django.utils import timezone
        return (self.status == 'published' and  # 只允许已发布的活动报名
                not self.is_full and
                timezone.now() <= self.registration_deadline)


class EventRegistration(models.Model):
    """活动报名记录"""
    STATUS_CHOICES = (
        ('registered', '已报名'),
        ('cancelled', '已取消'),
        ('attended', '已参加'),
        ('no_show', '未到场'),
    )

    event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='registrations')
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='event_registrations')
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='registered')
    registration_time = models.DateTimeField(auto_now_add=True, verbose_name='报名时间')
    cancellation_time = models.DateTimeField(null=True, blank=True, verbose_name='取消时间')
    notes = models.TextField(blank=True, verbose_name='备注')

    class Meta:
        unique_together = ('event', 'user')
        ordering = ['-registration_time']

    def __str__(self):
        return f"{self.user.username} - {self.event.title}"


class EventReview(models.Model):
    """活动评价"""
    event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='reviews')
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='event_reviews')
    rating = models.IntegerField(choices=[(i, i) for i in range(1, 6)], verbose_name='评分')
    comment = models.TextField(verbose_name='评论')
    images = models.JSONField(default=list, blank=True, verbose_name='图片')  # 存储图片URL列表
    is_anonymous = models.BooleanField(default=False, verbose_name='匿名评价')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ('event', 'user')
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.user.username}对{self.event.title}的评价"


class EventDiscussion(models.Model):
    """活动讨论区"""
    event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='discussions')
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='discussion_posts')
    content = models.TextField(verbose_name='内容')
    images = models.JSONField(default=list, blank=True, verbose_name='图片')
    likes_count = models.IntegerField(default=0, verbose_name='点赞数')
    dislikes_count = models.IntegerField(default=0, verbose_name='点踩数')
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='replies')
    is_pinned = models.BooleanField(default=False, verbose_name='置顶')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    is_deleted = models.BooleanField(default=False, verbose_name='已删除')
    deleted_at = models.DateTimeField(null=True, blank=True)
    class Meta:
        ordering = ['-is_pinned', '-created_at']

    def __str__(self):
        return f"{self.user.username}在{self.event.title}的讨论"

    @property
    def can_delete(self):
        """检查是否可以删除（作者或活动组织者）"""
        return True


class DiscussionLike(models.Model):
    """评论点赞"""
    discussion = models.ForeignKey(EventDiscussion, on_delete=models.CASCADE, related_name='likes')
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='discussion_likes')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('discussion', 'user')
class DiscussionDislike(models.Model):
    """评论点踩"""
    discussion = models.ForeignKey(EventDiscussion, on_delete=models.CASCADE, related_name='dislikes')
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='discussion_dislikes')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('discussion', 'user')

class EventImage(models.Model):
    """活动图片"""
    event = models.ForeignKey(Event, on_delete=models.CASCADE,related_name='images')
    image = models.ImageField(
        upload_to='event_images/%Y/%m/%d/',  # OSS中的存储路径
        verbose_name='活动图片',
        storage=CustomOssStorage()  # 直接指定存储后端
    )
    caption = models.CharField(max_length=200, blank=True)
    is_primary = models.BooleanField(default=False, verbose_name='主图')
    uploaded_by = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.event.title}的图片"

    @property
    def image_url(self):
        """获取图片完整URL"""
        if self.image and hasattr(self.image, 'url'):
            return self.image.url
        return None

    def delete(self, *args, **kwargs):
        """重写delete方法，删除数据库记录前先删除OSS文件"""
        if self.image:
            # 删除OSS上的文件
            try:
                default_storage.delete(self.image.name)
                print(f"✓ 已删除OSS文件: {self.image.name}")
            except Exception as e:
                print(f"⚠ 删除OSS文件失败: {e}")

        # 调用父类的delete方法删除数据库记录
        super().delete(*args, **kwargs)


class Reward(models.Model):
    """积分商城奖励"""
    REWARD_TYPES = (
        ('coupon', '优惠券'),
        ('privilege', '特权'),
        ('physical', '实物奖励'),
    )

    name = models.CharField(max_length=100, verbose_name='奖励名称')
    description = models.TextField(verbose_name='奖励描述')
    reward_type = models.CharField(max_length=20, choices=REWARD_TYPES)
    points_required = models.IntegerField(verbose_name='所需积分')
    image = models.ImageField(upload_to='reward_images/', null=True, blank=True)
    stock_quantity = models.IntegerField(default=0, verbose_name='库存数量')
    is_active = models.BooleanField(default=True, verbose_name='是否激活')
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name


class RewardRedemption(models.Model):
    """积分兑换记录"""
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='redemptions')
    reward = models.ForeignKey(Reward, on_delete=models.CASCADE, related_name='redemptions')
    points_used = models.IntegerField(verbose_name='使用积分')
    redemption_time = models.DateTimeField(auto_now_add=True)
    status = models.CharField(max_length=20, choices=(
        ('pending', '待处理'),
        ('completed', '已完成'),
        ('cancelled', '已取消'),
    ), default='pending')

    class Meta:
        ordering = ['-redemption_time']

    def __str__(self):
        return f"{self.user.username}兑换{self.reward.name}"

class CommunityPost(models.Model):
    POST_TYPES = (
        ('discussion', '讨论'),
        ('experience', '经验分享'),
        ('question', '提问'),
        ('announcement', '公告'),
    )

    POST_STATUS = (
        ('published', '已发布'),
        ('draft', '草稿'),
        ('reported', '被举报'),
        ('hidden', '已隐藏'),
    )

    title = models.CharField(max_length=200, verbose_name='帖子标题')
    content = models.TextField(verbose_name='帖子内容')
    author = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='community_posts')
    post_type = models.CharField(max_length=20, choices=POST_TYPES, default='discussion')
    event = models.ForeignKey(Event, on_delete=models.SET_NULL, null=True, blank=True, related_name='community_posts')

    # 状态管理
    status = models.CharField(max_length=20, choices=POST_STATUS, default='published', verbose_name='帖子状态')
    is_pinned = models.BooleanField(default=False, verbose_name='置顶')
    is_featured = models.BooleanField(default=False, verbose_name='精选')
    is_active = models.BooleanField(default=True, verbose_name='是否激活')

    # 举报相关字段
    report_count = models.IntegerField(default=0, verbose_name='举报次数')
    last_reported_at = models.DateTimeField(null=True, blank=True, verbose_name='最后举报时间')

    # 统计信息
    views_count = models.IntegerField(default=0, verbose_name='浏览数')
    likes_count = models.IntegerField(default=0, verbose_name='点赞数')
    comments_count = models.IntegerField(default=0, verbose_name='评论数')

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-is_pinned', '-created_at']
        verbose_name = '社区帖子'
        verbose_name_plural = '社区帖子'

    def __str__(self):
        return self.title

    @property
    def can_edit(self):
        """检查是否可以编辑"""
        return self.status in ['draft', 'reported']

    def move_to_draft(self, report_reason="", reported_by=None):
        """将帖子移动到草稿箱"""
        # 创建草稿记录
        draft = PostDraft.objects.create(
            title=self.title,
            content=self.content,
            author=self.author,
            post_type=self.post_type,
            event=self.event,
            status='reported',
            report_reason=report_reason,
            reported_by=reported_by,
            reported_at=timezone.now()
        )

        # 更新帖子状态
        self.status = 'hidden'
        self.save()

        return draft
class PostDraft(models.Model):
    """帖子草稿箱"""
    DRAFT_STATUS = (
        ('draft', '草稿'),
        ('reported', '被举报'),
        ('pending_review', '待审核'),
    )

    title = models.CharField(max_length=200, verbose_name='草稿标题')
    content = models.TextField(verbose_name='草稿内容')
    author = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='post_drafts')
    post_type = models.CharField(max_length=20, choices=CommunityPost.POST_TYPES, default='discussion')
    event = models.ForeignKey(Event, on_delete=models.SET_NULL, null=True, blank=True, related_name='draft_posts')

    # 状态管理
    status = models.CharField(max_length=20, choices=DRAFT_STATUS, default='draft', verbose_name='草稿状态')
    report_reason = models.TextField(blank=True, verbose_name='举报原因')
    reported_by = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True, blank=True,
                                    related_name='reported_drafts', verbose_name='举报人')

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    reported_at = models.DateTimeField(null=True, blank=True, verbose_name='举报时间')

    class Meta:
        ordering = ['-updated_at']
        verbose_name = '帖子草稿'
        verbose_name_plural = '帖子草稿'

    def __str__(self):
        return f"{self.author.username}的草稿 - {self.title}"

    def publish(self):
        """将草稿发布为正式帖子"""
        post = CommunityPost.objects.create(
            title=self.title,
            content=self.content,
            author=self.author,
            post_type=self.post_type,
            event=self.event
        )
        # 创建用户动态
        UserActivity.objects.create(
            user=self.author,
            activity_type='post_created',
            target_post=post
        )
        self.delete()  # 发布后删除草稿
        return post

    def restore_from_reported(self):
        """从被举报状态恢复到草稿状态"""
        self.status = 'draft'
        self.report_reason = ''
        self.reported_by = None
        self.reported_at = None
        self.save()

class PostComment(models.Model):
    """帖子评论"""
    post = models.ForeignKey(CommunityPost, on_delete=models.CASCADE, related_name='comments')
    author = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='post_comments')
    content = models.TextField(verbose_name='评论内容')
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='replies')

    # 统计
    likes_count = models.IntegerField(default=0, verbose_name='点赞数')

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['created_at']

    def __str__(self):
        return f"{self.author.username}对{self.post.title}的评论"


class PostLike(models.Model):
    """帖子点赞"""
    post = models.ForeignKey(CommunityPost, on_delete=models.CASCADE, related_name='likes')
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='post_likes')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('post', 'user')


class CommentLike(models.Model):
    """评论点赞"""
    comment = models.ForeignKey(PostComment, on_delete=models.CASCADE, related_name='likes')
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='comment_likes')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('comment', 'user')

from Customer.models import CustomUser
class UserMessage(models.Model):
    """用户私信"""
    # sender = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='sent_messages')
    # receiver = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='received_messages')
    sender = models.ForeignKey(
        CustomUser,
        on_delete=models.CASCADE,
        related_name='sent_user_messages'
    )
    receiver = models.ForeignKey(
        CustomUser,
        on_delete=models.CASCADE,
        related_name='received_user_messages'
    )
    content = models.TextField(verbose_name='消息内容')
    is_read = models.BooleanField(default=False, verbose_name='是否已读')

    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = '用户私信'
        verbose_name_plural = '用户私信'

    def __str__(self):
        return f"{self.sender.username} -> {self.receiver.username}"


class UserActivity(models.Model):
    """用户动态"""
    ACTIVITY_TYPES = (
        ('event_created', '创建活动'),
        ('event_joined', '参加活动'),
        ('post_created', '发布帖子'),
        ('comment_created', '发表评论'),
        ('review_created', '发布评价'),
    )

    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='activities')
    activity_type = models.CharField(max_length=20, choices=ACTIVITY_TYPES)
    target_event = models.ForeignKey(Event, on_delete=models.CASCADE, null=True, blank=True)
    target_post = models.ForeignKey(CommunityPost, on_delete=models.CASCADE, null=True, blank=True)
    target_comment = models.ForeignKey(PostComment, on_delete=models.CASCADE, null=True, blank=True)

    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = '用户动态'
        verbose_name_plural = '用户动态'

    def __str__(self):
        return f"{self.user.username}的{self.get_activity_type_display()}"

# 积分相关模型
class PointTransaction(models.Model):
    """积分交易记录"""
    TRANSACTION_TYPES = (
        ('earn', '获得'),
        ('spend', '消费'),
        ('refund', '退还'),
    )

    SOURCE_TYPES = (
        ('event_create', '创建活动'),
        ('event_join', '参加活动'),
        ('event_review', '活动评价'),
        ('post_create', '发布帖子'),
        ('comment_create', '发表评论'),
        ('daily_login', '每日登录'),
        ('profile_complete', '完善资料'),
        ('reward_redemption', '积分兑换'),
        ('system_bonus', '系统奖励'),
    )

    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='point_transactions')
    transaction_type = models.CharField(max_length=20, choices=TRANSACTION_TYPES)
    points = models.IntegerField(verbose_name='积分数量')
    source_type = models.CharField(max_length=20, choices=SOURCE_TYPES, verbose_name='来源类型')
    description = models.CharField(max_length=200, verbose_name='描述')
    related_event = models.ForeignKey(Event, on_delete=models.SET_NULL, null=True, blank=True)
    related_post = models.ForeignKey('CommunityPost', on_delete=models.SET_NULL, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = '积分交易记录'
        verbose_name_plural = '积分交易记录'

    def __str__(self):
        return f"{self.user.username} - {self.get_transaction_type_display()} {self.points}积分"

class PointRule(models.Model):
    """积分规则"""
    RULE_TYPES = (
        ('event_create', '创建活动'),
        ('event_join', '参加活动'),
        ('event_review', '活动评价'),
        ('post_create', '发布帖子'),
        ('comment_create', '发表评论'),
        ('daily_login', '每日登录'),
        ('profile_complete', '完善资料'),
        ('event_organizer_bonus', '活动组织者奖励'),
    )

    rule_type = models.CharField(max_length=50, choices=RULE_TYPES, unique=True, verbose_name='规则类型')
    points = models.IntegerField(verbose_name='积分值')
    daily_limit = models.IntegerField(default=0, verbose_name='每日上限')
    description = models.TextField(verbose_name='规则描述')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = '积分规则'
        verbose_name_plural = '积分规则'

    def __str__(self):
        return f"{self.get_rule_type_display()} - {self.points}积分"

class Checkin(models.Model):
    """活动签到模型"""
    event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='checkins')
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='checkins')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ['event', 'user']  # 防止重复签到
        verbose_name = '活动签到'
        verbose_name_plural = '活动签到'

    def __str__(self):
        return f"{self.user.username} - {self.event.title}"